<template>
  <TableListLayout title="用户列表">
    <template #button>
      <DefaultButton @add="onAdd" @search="onSearch" @remove="onBatchRemove" @refresh="pull" />
    </template>
    <DefaultTable
      ref="table"
      :loading="lLoading"
      :data="data"
      stripe
      :columns="[
        {
          type: 'avatar',
          prop: 'avatar',
          label: '头像',
          data: (row: GApiUser) => (row.avatar ? row.avatar.path : appStore.config.DefaultAvatar),
          props: {
            'header-align': 'center',
          },
        },
        { type: 'text', prop: 'username', label: '用户名' },
        { type: 'text', prop: 'phone', label: '手机号' },
        { type: 'text', prop: 'email', label: '邮箱' },
      ]"
      @detail="onDetail"
      @edit="onEdit"
      @remove="onRemove"
    />
    <template #pagination>
      <DefaultPagination v-model:page="page" v-model:size="size" :total="total" />
    </template>
  </TableListLayout>
</template>

<script setup lang="ts">
import DefaultDetail from '@/components/detail/DefaultDetail.vue'
import DefaultForm from '@/components/form/DefaultForm.vue'
import { useListRequest, useRequest } from '@/hooks'
import { useDefaultDetail } from '@/hooks/useDefaultDetail'
import { useDefaultForm } from '@/hooks/useDefaultForm'
import TableListLayout from '@/layouts/TableListLayout.vue'
import { useStore } from '@/stores'
import { openDialog } from '@/utils/component'

const appStore = useStore()

const tableRef = useTemplateRef('table')

const {
  where,
  loading: lLoading,
  data,
  page,
  size,
  total,
  pull,
} = useListRequest('/api/user', 'GET')
const { request: aRequest, data: aData } = useRequest('/api/user', 'POST')
const { loading: sLoading, request: sRequest, data: sData } = useRequest('/api/user/:id', 'GET')
const { request: uRequest, data: uData } = useRequest('/api/user/:id', 'PUT')
const { request: dRequest } = useRequest('/api/user/:id', 'DELETE')

const {
  request: roleRequest,
  data: roleData,
  loading: roleLoading,
} = useRequest('/api/role/all/data', 'GET')
const {
  request: permissionRequest,
  data: permissionData,
  loading: permissionLoading,
} = useRequest('/api/permission/all/data', 'GET')

onMounted(() => {
  pull()
})

const { props: searchProps } = useDefaultForm({
  gridTemplateAreas: `
                            "username username"
                            "phone phone"
                            "email email"
                        `,
  loading: () => false,
  items: () => [
    { model: 'username', type: 'input', label: '用户名', default: where.value?.username },
    { model: 'phone', type: 'input', label: '手机号', default: where.value?.phone },
    { model: 'email', type: 'input', label: '邮箱', default: where.value?.email },
  ],
})
const onSearch = () => {
  openDialog(
    DefaultForm,
    searchProps,
    {
      title: '用户搜索',
      width: 800,
      appendToBody: true,
      destroyOnClose: true,
      closeOnClickModal: false,
      closeOnPressEscape: false,
      isCancel: false,
    },
    {
      onConfirm: async (value) => {
        await pull(value)
        return true
      },
    },
  )
}

const roleSelectOptions = computed(
  () =>
    roleData.value?.map((role) => ({ label: `${role.code}(${role.name})`, value: role.id })) || [],
)
const permissionSelectOptions = computed(
  () =>
    permissionData.value?.map((permission) => ({
      label: `${permission.code}(${permission.name})`,
      value: permission.id,
    })) || [],
)

const { props: addProps } = useDefaultForm({
  gridTemplateAreas: `
                            "username password"
                            "phone email"
                            "roles permissions"
                            "avatar avatar"
                        `,
  loading: () => roleLoading.value && permissionLoading.value,
  items: () => [
    { model: 'username', type: 'input', label: '用户名', props: { placeholder: '请输入用户名' } },
    { model: 'password', type: 'input', label: '密码', props: { type: 'password' } },
    { model: 'phone', type: 'input', label: '手机号' },
    { model: 'email', type: 'input', label: '邮箱' },
    {
      model: 'roles',
      type: 'select',
      label: '角色',
      options: roleSelectOptions.value,
      props: { multiple: true, loading: roleLoading.value },
      default: () => [],
    },
    {
      model: 'permissions',
      type: 'select',
      label: '权限',
      options: permissionSelectOptions.value,
      props: { multiple: true, loading: permissionLoading.value },
      default: () => [],
    },
    {
      model: 'avatar',
      type: 'image-upload',
      label: '头像',
      default: null,
      props: {
        action: '/api/file/upload',
        method: 'POST',
      },
    },
  ],
  formProps: () => ({
    labelWidth: 100,
    rules: {
      username: [{ required: true, message: '必须输入用户名', trigger: 'blur' }],
    },
  }),
})

const onAdd = () => {
  roleRequest()
  permissionRequest()
  openDialog(
    DefaultForm,
    addProps,
    {
      title: '用户新增',
      width: 800,
      appendToBody: true,
      destroyOnClose: true,
      closeOnClickModal: false,
      closeOnPressEscape: false,
      isCancel: false,
    },
    {
      onConfirm: async (value) => {
        await aRequest(value as Omit<GApiUser, 'id'>)
        if (!aData.value) {
          return false
        }
        await pull()
        return true
      },
    },
  )
}

const { props: detailProps } = useDefaultDetail({
  loading: () => sLoading.value,
  items: () => {
    if (!sData.value) {
      return []
    }
    return [
      {
        type: 'text',
        label: 'ID',
        data: sData.value.id,
      },
      {
        type: 'text',
        label: '用户名',
        data: sData.value.username,
      },
      {
        type: 'text',
        label: '手机号',
        data: sData.value.phone,
      },
      {
        type: 'text',
        label: '邮箱',
        data: sData.value.email,
      },
      {
        type: 'avatar',
        label: '头像',
        data: sData.value.avatar?.path || appStore.config.DefaultAvatar,
      },
    ]
  },
})

const onDetail = (row: GApiUser) => {
  sRequest({
    ':id': row.id,
  })
  openDialog(DefaultDetail, detailProps, {
    title: '用户详情',
    width: 800,
    appendToBody: true,
    destroyOnClose: true,
    closeOnClickModal: false,
    closeOnPressEscape: false,
    isConfirm: false,
  })
}

const { props: editProps } = useDefaultForm({
  gridTemplateAreas: `
                            "username phone"
                            "email ."
                            "roles roles"
                            "permissions permissions"
                            "avatar avatar"
                        `,
  loading: () => roleLoading.value && permissionLoading.value && sLoading.value,
  items: () => {
    if (!sData.value) {
      return []
    }
    return [
      { model: 'username', type: 'input', label: '用户名', default: sData.value.username },
      { model: 'phone', type: 'input', label: '手机号', default: sData.value.phone },
      { model: 'email', type: 'input', label: '邮箱', default: sData.value.email },
      {
        model: 'roles',
        type: 'select',
        label: '角色',
        options: roleSelectOptions.value,
        props: { multiple: true, style: { width: '240px' }, loading: roleLoading.value },
        default: sData.value.roles.map((role) => role.id),
      },
      {
        model: 'permissions',
        type: 'select',
        label: '权限',
        options: permissionSelectOptions.value,
        props: { multiple: true, loading: permissionLoading.value },
        default: sData.value.permissions.map((permission) => permission.id),
      },
      {
        model: 'avatar',
        type: 'image-upload',
        label: '头像',
        default: sData.value.avatar,
        props: {
          action: '/api/file/upload',
          method: 'POST',
        },
      },
    ]
  },
})

const onEdit = async (row: GApiUser) => {
  roleRequest()
  permissionRequest()
  sRequest({
    ':id': row.id,
  })
  openDialog(
    DefaultForm,
    editProps,
    {
      title: '用户编辑',
      width: 800,
      appendToBody: true,
      destroyOnClose: true,
      closeOnClickModal: false,
      closeOnPressEscape: false,
      isCancel: false,
    },
    {
      onConfirm: async (value) => {
        await uRequest({
          ':id': value.id,
          ...(value as GApiUser),
        })
        if (!uData.value) {
          return false
        }
        await pull()
        return true
      },
    },
  )
}

const onRemove = async (row: GApiUser) => {
  lLoading.value = true
  await dRequest({
    ':id': row.id,
  })
  await pull()
}
const onBatchRemove = async () => {
  const rows = tableRef.value?.getSelectionRows() || []
  if (rows.length === 0) {
    return
  }
  lLoading.value = true
  await dRequest({
    ':id': rows.map((row) => row.id).join(encodeURIComponent(' ')),
  })
  await pull()
}
</script>

<style scoped lang="scss"></style>
